/**
    ATClab - scriptable Air Traffic Control simulations.
    Copyright (C) 2010 openatclab@gmail.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
**/

#include "audio_player.h"

#include <qapplication.h>
#include <qdir.h>
#include <qfileinfo.h>
#include <qsound.h>
#include <qtimer.h>

#include <sstream>

/*
#ifdef WIN32
	#include "windows.h"
	#include "mmsystem.h"
#endif
*/

using namespace atc;

////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
//
//--------------------------------------------------------------------------------------------------
// 
//


/*!
 *
 */
AudioPlayer::AudioPlayer( QObject *parent )
		: QObject( parent )
		, _bites()
		, _queue()
		, _finished( true )
{}

/*!
 *
 */
AudioPlayer::~AudioPlayer() {
	for ( SoundBiteMap::iterator it = _bites.begin(); it != _bites.end(); ++it )
			if ( it->second ) { delete it->second; it->second = 0; }
}


//--------------------------------------------------------------------------------------------------
// [public]
//

/*!
 *
 */
SoundBite AudioPlayer::register_sound_bite( const std::string &name, int duration, bool priority ) {
	if ( ! _bites.count( name ) ) 
			_bites[ name ] = new AudioTrack( name, duration, priority );
	return _bites[ name ];
}

/*!
 *
 */
void AudioPlayer::queue( SoundBite bite ) {
	if ( bite->priority ) 
	{
		_queue.push_front( bite );
	}
	else                  
	{
		_queue.push_back( bite );
	}
	
	if ( _finished ) 
	{
		_finished = false;
		play();
	}
}


//--------------------------------------------------------------------------------------------------
// [private slots]
//

/*!
 *
 */
void AudioPlayer::play() {
	if ( _queue.empty() ) 
	{
		_finished = true;
		return;
	}

	SoundBite bite = _queue.front();
	_queue.pop_front();

	bite->sound.play();
	QTimer::singleShot( bite->length, this, SLOT( play() ) );
}


//--------------------------------------------------------------------------------------------------
// [private slots]
//

/*
#ifdef _WIN32

int AudioPlayer::duration( const std::string &name ) {

	QFileInfo fileinfo( QDir(qApp->applicationDirPath()), name.c_str() );

	MCI_OPEN_PARMS lpOpen;
	lpOpen.lpstrDeviceType  = (LPWORD) MCI_DEVTYPE_WAVEFORM_AUDIO;
	lpOpen.lpstrElementName = (LPWORD) fileinfo.absFilePath().latin1();

	MCIERROR openErr = mciSendCommand( 
			0, 
			MCI_OPEN, 
			MCI_WAIT | MCI_OPEN_ELEMENT | MCI_OPEN_TYPE_ID, 
			(DWORD)(LPVOID) &lpOpen 
		);
	if ( openErr ) {
		std::string openErrMsg = error_text( openErr, name.c_str() );
		return 0;
	}


	MCI_SET_PARMS lpSet;
	lpSet.dwTimeFormat = MCI_FORMAT_MILLISECONDS;

	MCIERROR setErr = mciSendCommand(
			lpOpen.wDeviceID,
			MCI_SET,
			MCI_SET_TIME_FORMAT,
			(DWORD)(LPVOID) &lpSet
		);
	if ( setErr )
			std::string setErrMsg = error_text( setErr, name.c_str() );


	MCI_PLAY_PARMS mciPlayParms;
	
	MCIERROR playErr = mciSendCommand(
			lpOpen.wDeviceID,
			MCI_PLAY, 
			MCI_WAIT, 
			(DWORD)(LPVOID)&mciPlayParms
		);
	if ( playErr ) {
		std::string playErrMsg = error_text( playErr, name.c_str() );
	}

	MCI_STATUS_PARMS lpStatus;
	lpStatus.dwCallback = 0;
	lpStatus.dwItem = MCI_STATUS_LENGTH;
	lpStatus.dwTrack = 0;

	MCIERROR statusErr = mciSendCommand(
			lpOpen.wDeviceID,
			MCI_STATUS,
			MCI_WAIT | MCI_STATUS_ITEM | MCI_TRACK,
			(DWORD)(LPVOID) &lpStatus
		);
	if ( statusErr ) {
		std::string statusErrMsg = error_text( statusErr, name.c_str() );
	}

	MCIERROR closeErr = mciSendCommand(
			lpOpen.wDeviceID,
			MCI_WAIT | MCI_CLOSE,
			0,
			NULL
		);
	if ( closeErr ) {
		std::string closeErrMsy = error_text( closeErr, name.c_str() );
	}


	return lpStatus.dwReturn;
}



std::string AudioPlayer::error_text( int mcierr, const char *msg )
{
	char pszText[255];
	mciGetErrorStringA(mcierr, pszText, 255);

	std::ostringstream oss;
	oss << msg << " : " << pszText;

	return oss.str();
}

#endif
*/
////////////////////////////////////////////////////////////////////////////////////////////////////
